home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994 Marc Parmet.
- * This file is part of the Macintosh port of GNU Emacs.
- *
- * GNU Emacs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
- #include <MacHeaders>
- #include <Printing.h>
- #include <Packages.h>
-
- #define PostScriptBegin 190
- #define PostScriptEnd 191
- #define PostScriptHandle 192
-
- #define LEFTSPACE 2
- #define TOPSPACE 2
- #define TABWIDTH 8
- #define EXTRAHEADROOM 10
-
- #define EOF (-1)
-
- extern char border_rect,print_format;
-
- static short refnum;
- static FSSpec spec;
- static char have_spec;
- static TPrStatus myStRec;
- static int pagenum;
- static char notify_operation;
- static char pushback;
-
- static int
- ungetc(char c)
- {
- pushback = c;
- }
-
- static int
- getc(void)
- {
- long n;
- short err;
- unsigned char c;
-
- if (pushback != -1) {
- c = pushback;
- pushback = -1;
- return c;
- }
-
- n = 1;
- err = FSRead(refnum,&n,&c);
- if (err) return EOF;
- return (int)c;
- }
-
- static void
- idle_action(void)
- {
- EvQElPtr q;
-
- if (PrError() == noErr)
- for (q = (EvQElPtr)GetEvQHdr()->qHead; q != 0L; q = (EvQElPtr)q->qLink)
- if (q->evtQWhat == keyDown && (q->evtQModifiers & cmdKey) &&
- (char)q->evtQMessage == '.')
- PrSetError(iPrAbort);
-
- notify_message(notify_operation,notify_operation ? myStRec.iCurPage : pagenum,
- myStRec.iTotPages,spec.name);
- }
-
- static unsigned char *linebuf;
- static int linebuflen;
- static Point run_start;
- static int current_row,current_col,headspace,lineHeight;
- static FontInfo fi;
-
- static void
- flush_run(void)
- {
- Point pt;
-
- pt.h = LEFTSPACE + run_start.h * fi.widMax;
- pt.v = TOPSPACE + headspace + lineHeight * run_start.v + fi.ascent;
- MoveTo(pt.h,pt.v);
- DrawText(linebuf,0,linebuflen);
- }
-
- static void
- new_run(void)
- {
- linebuflen = 0;
- run_start.h = current_col;
- run_start.v = current_row;
- }
-
- static int
- get_job(char *driver_open,THPrint *hPrint)
- {
- int err,invalid,accepted;
-
- retry:
-
- PrOpen();
- if (PrError()) goto bail;
- *driver_open = 1;
-
- err = get_preference('PREC',128,hPrint);
- if (err) {
- // Never printed before. Must do page setup.
- PrClose(); *driver_open = 0;
- if (Alert(128,0L) == 1) {
- err = do_page_setup();
- if (err) goto bail;
- if (Alert(133,0L) != 1) goto bail;
- goto retry;
- }
- }
-
- invalid = PrValidate(*hPrint);
- if (PrError()) goto bail;
- if (invalid) {
- // Not the same printer as last time. Must do page setup
- PrClose(); *driver_open = 0;
- if (Alert(129,0L) == 1) {
- err = do_page_setup();
- if (err) goto bail;
- if (Alert(133,0L) != 1) goto bail;
- goto retry;
- }
- }
-
- accepted = PrJobDialog(*hPrint);
- if (PrError() || !accepted) goto bail;
-
- return 0;
-
- bail:
- return 1;
- }
-
- static void
- print_text_file(void)
- {
- int c;
- THPrint hPrint;
- TPPrPort myPrPort;
- unsigned long dateTime;
- short err;
- unsigned char date[256],time[256],u[256],v[20];
- char doc_open,page_complete,doc_complete,notify_open,driver_open,page_open;
- int lines_per_page,cols_per_page;
-
- linebuf = 0L;
- hPrint = 0L;
- doc_open = 0;
- page_open = 0;
- notify_open = 0;
- driver_open = 0;
- pushback = -1;
-
- if (get_job(&driver_open,&hPrint)) goto bail;
-
- // Tech Note M.IM.pIdleProc says put this next statement here.
- (**hPrint).prJob.pIdleProc = NewPrIdleProc(idle_action);
-
- myPrPort = PrOpenDoc(hPrint,0L,0L);
- if (PrError()) goto bail;
- doc_open = 1;
-
- GetDateTime(&dateTime);
- IUDateString(dateTime,abbrevDate,date);
- IUTimeString(dateTime,0,time);
- pagenum = 1;
-
- notify_start();
- notify_open = 1;
- notify_operation = 0;
-
- doc_complete = 0;
- while (!doc_complete) {
- // Each pass through this loop is a page.
- notify_message(0,pagenum,0,spec.name);
-
- PrOpenPage(myPrPort,0L);
- if (PrError()) goto bail;
- page_open = 1;
-
- SetPort((GrafPtr)myPrPort);
- TextFont(monaco);
- TextSize(9);
-
- if (border_rect) FrameRect(&myPrPort->gPort.portRect);
-
- if (linebuf == 0L) {
- GetFontInfo(&fi);
- lineHeight = fi.ascent + fi.descent + fi.leading;
- headspace = (print_format ? lineHeight + EXTRAHEADROOM : 0);
- lines_per_page = (myPrPort->gPort.portRect.bottom -
- myPrPort->gPort.portRect.top - 2*TOPSPACE -
- headspace + fi.leading) / lineHeight;
- cols_per_page = (myPrPort->gPort.portRect.right -
- myPrPort->gPort.portRect.left - 2*LEFTSPACE) / fi.widMax;
-
- if (linebuf == 0L) {
- linebuf = (unsigned char *)NewPtr(cols_per_page+1);
- if (MemError()) goto bail;
- }
- }
-
- if (print_format) {
- // Write name, date, and page number
-
- MoveTo(LEFTSPACE,TOPSPACE + lineHeight - fi.leading - fi.descent);
- TextFace(bold);
-
- if (have_spec) {
- DrawString(spec.name);
- Move(20,0);
- }
-
- DrawString(date);
- Move(20,0);
- DrawString(time);
-
- GetIndString(u,128,6);
- NumToString(pagenum,v); pstrcat(u,v);
- MoveTo(myPrPort->gPort.portRect.right - LEFTSPACE - StringWidth(u),
- myPrPort->gPort.pnLoc.v);
- DrawString(u);
-
- TextFace(normal);
- }
-
- current_row = 0;
- current_col = 0;
- new_run();
-
- // Keep reading and printing characters until we walk off the bottom of
- // the page.
- page_complete = 0;
- while (!page_complete) {
- if ((TickCount() & 63) == 0) {
- idle_action();
- if (PrError()) goto bail;
- }
-
- c = getc();
- switch (c) {
- case EOF:
- flush_run();
- page_complete = doc_complete = 1;
- break;
- case '\t':
- flush_run();
- current_col += TABWIDTH - current_col % TABWIDTH;;
- if (current_col >= cols_per_page) {
- ++current_row;
- if (current_row == lines_per_page)
- page_complete = 1;
- else {
- current_col = 0;
- new_run();
- }
- }
- else
- new_run();
- break;
- case 'L' & 0x1f:
- flush_run();
- page_complete = 1;
- break;
- case '\n':
- case '\r':
- flush_run();
- ++current_row;
- if (current_row == lines_per_page)
- page_complete = 1;
- else {
- current_col = 0;
- new_run();
- }
- break;
- default:
- if (current_col == cols_per_page) {
- ungetc(c);
- flush_run();
- ++current_row;
- if (current_row == lines_per_page)
- page_complete = 1;
- else {
- current_col = 0;
- new_run();
- }
- }
- else {
- linebuf[linebuflen] = c;
- ++linebuflen;
- ++current_col;
- }
- break;
- }
- }
-
- PrClosePage(myPrPort); page_open = 0;
- if (PrError()) goto bail;
- ++pagenum;
- }
-
- PrCloseDoc(myPrPort); doc_open = 0;
- if (PrError()) goto bail;
-
- notify_operation = 1;
- if ((**hPrint).prJob.bJDocLoop == bSpoolLoop) {
- notify_message(1,0,0,spec.name);
- PrPicFile(hPrint,0L,0L,0L,&myStRec);
- }
-
- bail:
- if (page_open) PrClosePage(myPrPort);
- if (doc_open) PrCloseDoc(myPrPort);
- if (notify_open) notify_end();
- if (linebuf) DisposPtr((Ptr)linebuf);
- if (hPrint) DisposHandle((Handle)hPrint);
- if (driver_open) PrClose();
- }
-
- static void
- print_postscript_file(void)
- {
- /* What follows is not the right way to send postscript directly to
- a printer, but only a kludge. One day we'll make it right. */
-
- #define bufmax 4096
- long n;
- Handle buffer;
- THPrint hPrint;
- TPPrPort myPrPort;
- short err;
- char doc_open,doc_complete,notify_open,driver_open,page_open;
-
- hPrint = 0L;
- buffer = 0L;
- doc_open = 0;
- page_open = 0;
- notify_open = 0;
- driver_open = 0;
-
- buffer = NewHandle(bufmax);
- if (buffer == 0L) goto bail;
-
- if (get_job(&driver_open,&hPrint)) goto bail;
-
- // Tech Note M.IM.pIdleProc says put this next statement here.
- (**hPrint).prJob.pIdleProc = NewPrIdleProc(idle_action);
-
- myPrPort = PrOpenDoc(hPrint,0L,0L);
- if (PrError()) goto bail;
- doc_open = 1;
-
- notify_start();
- notify_open = 1;
- notify_operation = 1;
- notify_message(notify_operation,0,0,spec.name);
-
- PrOpenPage(myPrPort,0L);
- if (PrError()) goto bail;
- page_open = 1;
-
- SetPort((GrafPtr)myPrPort);
- MoveTo(-32000,-32000);
- Line(0,0);
-
- PicComment(PostScriptBegin,0,0L);
- while (1) {
- n = bufmax;
- HLock(buffer);
- err = FSRead(refnum,&n,*buffer);
- HUnlock(buffer);
- if (n == 0) break;
- if (err && err != eofErr) break;
- PicComment(PostScriptHandle,n,buffer);
- }
- PicComment(PostScriptEnd,0,0L);
-
- PrClosePage(myPrPort); page_open = 0;
- if (PrError()) goto bail;
-
- PrCloseDoc(myPrPort); doc_open = 0;
- if (PrError()) goto bail;
-
- if ((**hPrint).prJob.bJDocLoop == bSpoolLoop) {
- notify_message(notify_operation,0,0,spec.name);
- PrPicFile(hPrint,0L,0L,0L,&myStRec);
- }
-
- bail:
- if (page_open) PrClosePage(myPrPort);
- if (doc_open) PrCloseDoc(myPrPort);
- if (notify_open) notify_end();
- if (buffer) DisposHandle(buffer);
- if (hPrint) DisposHandle((Handle)hPrint);
- if (driver_open) PrClose();
- }
-
- void
- do_print_spec(FSSpec *spec0)
- {
- short err;
- char s[2];
- long n;
-
- have_spec = 1;
- spec = *spec0;
-
- err = FSpOpenDF(&spec,fsRdPerm,&refnum);
- if (err) return;
- n = 2;
- err = FSRead(refnum,&n,s);
- if (err && err != eofErr) { FSClose(refnum); return; }
- SetFPos(refnum,fsFromStart,0);
- if (n == 2 && s[0] == '%' && s[1] == '!')
- print_postscript_file();
- else
- print_text_file();
- FSClose(refnum);
- }
-